package influence.propagation.implementation;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import java.util.StringTokenizer;

import influence.propagation.core.Parser;
import influence.propagation.exception.InputFormatException;

public class DefaultGraphParser implements Parser {
	
	private static String DEL_1 = "<>";
	private static String DEL_2 = ",";
	protected static String REGEX_1 = "(?<=\\s|^)\\d+(?=\\s|$)";
	protected static String REGEX_2 = "[-+]?[0-9]*\\.?[0-9]+";

	private File file;
	private Scanner reader = null;
	private StringTokenizer triples = null;
	private StringTokenizer tokens = null;
	private boolean isOpened = false;

	public DefaultGraphParser(File file) {
		this.file = file;
	}

	@Override
	public void open() throws FileNotFoundException {
		reader = new Scanner(file);
		triples = new StringTokenizer(reader.nextLine(), DEL_1);
		tokens = new StringTokenizer(triples.nextToken(), DEL_2);
		isOpened = true;
	}

	@Override
	public void close() {
		reader.close();
		isOpened = false;
	}

	@Override
	public boolean hasMoreToken() {
		if (!isOpened) {
			return false;
		}
		if (!triples.hasMoreTokens() && !tokens.hasMoreTokens()
				&& !reader.hasNextLine()) {
			return false;
		}
		return true;
	}

	private void control(String token) throws InputFormatException {
		if (!token.matches(REGEX_1) && !token.matches(REGEX_2)) {
			throw new InputFormatException("Token non accettato:" + token);
		}
	}

	@Override
	public String getNextToken() throws InputFormatException {
		String res = null;
		if (tokens.hasMoreTokens()) {
			res = tokens.nextToken();
			control(res);
			return res;
		}
		if (triples.hasMoreTokens()) {
			tokens = new StringTokenizer(triples.nextToken(), DEL_2);
			if (tokens.hasMoreTokens()) {
				res = tokens.nextToken();
				control(res);
				return res;
			}
		}
		if (reader.hasNextLine()) {
			triples = new StringTokenizer(reader.nextLine(), DEL_1);
			if (triples.hasMoreTokens()) {
				tokens = new StringTokenizer(triples.nextToken(), DEL_2);
				if (tokens.hasMoreTokens()) {
					res = tokens.nextToken();
					control(res);
					return res;
				}
			}
		}
		throw new IllegalStateException("Non ci sono token");
	}
}
